﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace ShootMan
{
    public class GameEntry : UnityEngine.MonoBehaviour
    {
        void Start()
        {
            StartCoroutine(TestDelayOpenMainLayer());
        }

        IEnumerator TestDelayOpenMainLayer()
        {
            yield return LoadMetadataForAOTAssembliesData();
            shaco.GameInitComponent.InitFrameworkEnvironment();
#if DEBUG_WINDOW
            UnityGameFramework.Runtime.DebuggerComponent.InitFrameworkEnvironment();
#endif

            ShootManHelper.testInstance.Print();

            //设置资源加载包
            shaco.GameHelper.res.SetCurrentPackageName("DefaultPackage");

            //注册图集回调
            shaco.SpriteAtlasHelper.SetAtlasRequestedCallBack(OnSpriteAtlasRequestd);

            //加载本地化语言表
            var currentLanguage = shaco.GameHelper.datasave.ReadEnum<SystemLanguage>(GlobalDefines.SettingKeys.CURRENT_LANGUAGE, Application.systemLanguage);
            UpdateLocalization(currentLanguage);

            //连接服务器
            yield return ConnectServer();

            //打开游戏主界面
            shaco.GameHelper.ui.OpenUI<MainLayer>();
            yield return new shaco.WaitForUIBringToFront<MainLayer>();
            shaco.GameHelper.ui.OpenUI<TipLayer>(new TipLayer.OpenUIArg() { content = "delay open main layer success" });
        }

        static public void UpdateLocalization(SystemLanguage language)
        {
            var cfgLocalization = shaco.GameHelper.localization;
            cfgLocalization.Clear();
            foreach (var iter in cfg_localization.Instance)
            {
                switch (language)
                {
                    case SystemLanguage.ChineseSimplified:
                    case SystemLanguage.ChineseTraditional:
                    case SystemLanguage.Chinese: cfgLocalization.AddWithString(iter.KEY, iter.CN); break;
                    default: cfgLocalization.AddWithString(iter.KEY, iter.EN); break;
                }
            }
        }

        static void OnSpriteAtlasRequestd(string atlasName, System.Action<UnityEngine.U2D.SpriteAtlas> callback)
        {
            var atlasPath = shaco.GameHelper.atlasSettings.GetAtlasPath(atlasName);
            shaco.Log.Info("SpriteAtlasManager OnAtlasRequested: atlasPath=" + atlasPath, Color.white);
            var loadHandle = shaco.GameHelper.res.Load<UnityEngine.U2D.SpriteAtlas>(atlasPath);

            try
            {
                //关闭多余的引用计数
                callback(loadHandle.assetObject as UnityEngine.U2D.SpriteAtlas);
                shaco.GameHelper.res.Release(loadHandle);
            }
            catch (System.Exception e)
            {
                Debug.LogError("SpriteAtlasManager OnAtlasRequested erorr: atlasName=" + atlasName + " callbackLoadEnd=" + callback + " e=" + e);
            }
        }

        IEnumerator ConnectServer()
        {
            //监听回调数据
            NetServiceComponent.AddDataReceiveListener(e =>
            {
                if (e is NetEvent.S2C_Test)
                    shaco.Log.Info("id=" + e.messageID + " messsage=" + ((NetEvent.S2C_Test)e).message);
                // else
                //     shaco.Log.Info("id=" + e?.messageID);
            });

            //开始连接服务器
            var isConnectEnd = false;
            NetServiceComponent.Connect((success) =>
            {
                if (!success)
                {
                    //这里需要延迟加载tip，因为新的场景可能还未加载出来
                    shaco.Delay.Run(() =>
                    {
                        shaco.GameHelper.ui.OpenUI<TipLayer>(new TipLayer.OpenUIArg() { content = "connect server failed" });
                    }, 0.1f);
                }
                else
                {
                    Debug.Log("NetServiceComponent connect success");
                }
                isConnectEnd = true;
            });

            while (!isConnectEnd)
                yield return null;
        }

        IEnumerator LoadMetadataForAOTAssembliesData()
        {
            var PatchedAOTAssemblyList = new List<string>
            {
                "System.Core.dll",
                "System.dll",
#if UNITY_ANDROID
                "UnityEngine.AndroidJNIModule.dll",
#endif
                "UnityEngine.CoreModule.dll",
                "UnityEngine.UI.dll",
                "YooAsset.dll",
                "mscorlib.dll",
            };

            yield return shaco.HyridCLRHelper.LoadDll(PatchedAOTAssemblyList, "scripts", $"{GlobalDefines.HOTUPDATE_ROOT}ScriptsDll/AOT", "dll aot", (name, bytes) =>
            {
                var mode = HybridCLR.HomologousImageMode.SuperSet;
                Debug.Log($"LoadMetadataForAOTAssembly start:{name} mode:{mode}");
                try
                {
                    var err = HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(bytes, mode);
                    Debug.Log($"LoadMetadataForAOTAssembly end:{name} ret:{err}");
                }
                catch (System.Exception ex)
                {
                    Debug.LogError($"LoadMetadataForAOTAssembly error:{name}, e=" + ex);
                }
            });
        }
    }
}